#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <io.h>
#include <alloc.h>
#include <conio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <ctype.h>
#include <dir.h>

#define ITEM  100
FILE *file;
unsigned char dat[ITEM][256],d[2];
unsigned char string[ITEM][256];
unsigned char vn[ITEM];

int vl;
int find (unsigned char *dat1,unsigned char *hex)
{
    unsigned long len=strlen(dat1);
    unsigned long num=0,hnum=0;
    unsigned long i;
    for (i=0;i<len;i++)  {
        if (dat1[i]!=hex[hnum])  {
            if (dat1[i]=='?')  {
                i++;hnum=hnum+2;continue;
            }
            if (dat1[i]=='%')  {
                i++;
                for (num=0;num<32;num++)  {
                    if (dat1[i+1]==hex[hnum+num])  {
                        if (find(&dat1[i+1],&hex[hnum+num])==1)  return 1;
                    }
                }
            }
            return 0;
        }
        hnum++;
    }
    return 1;
}

int findvirus (char *filename)
{
    int fh;
    int rnum=1;
    unsigned char *buf;
    unsigned char *hex;
    unsigned char x1,x2;
    unsigned long rsize=5000;
    unsigned long flen,i,j;
    int v;
    memset (vn,'0',ITEM-1);
    if ((hex=(unsigned char *)farmalloc(10000))==NULL)  {
        puts ("Out of memory .");return 1;
    }
    if ((buf=(unsigned char *)farmalloc(5000))==NULL)  {
        puts ("Out of memory .");return 1;
    }
    fh=open (filename,O_BINARY);
    flen=filelength(fh);
    if (flen<=rsize)  {
        rsize=flen;rnum=0;
    }
    for (j=0;j<=rnum;j++)  {
        if (j==1)  lseek (fh,-rsize,2);
        else  lseek (fh,0,0);
        if (read(fh,buf,rsize)==-1)  {
            puts ("Read file ERROR .");return 0;
        }
        for (i=0;i<rsize;i++)  {
            x1=buf[i]/16;
            x2=buf[i]-x1*16;
            hex[2*i]=x1<10?x1+0x30:x1-10+0x41;
            hex[2*i+1]=x2<10?x2+0x30:x2-10+0x41;
        }
        for (v=0;v<=vl;v++)  {
            for (i=0;i<rsize;i++)  {
                if (hex[2*i]==dat[v][0]&&hex[2*i+1]==dat[v][1])
                    if (find(dat[v],&hex[2*i])==1)  {
                        if (vn[v]=='0')  {
                            vn[v]='1';
                            puts (" ");
                            puts (string[v]);
                        }
                    }
            }
        }
    }
    farfree (hex);
    farfree (buf);
    close (fh);
    return 0;
}

void findfile()
{
    int p,hav,x,y,len;
    struct ffblk dirment,fname;
    char path[256];
    getcwd (path,256);
    hav=findfirst ("*.*",&fname,FA_RDONLY|FA_HIDDEN|FA_SYSTEM);
    while (!hav)  {
        x=wherex();
        len=strlen(path);
        clreol();
        if (len!=3)  printf ("Scaning %s\\%s",path,fname.ff_name);
        else printf ("Scaning %s%s",path,fname.ff_name);
        if ((strstr(fname.ff_name,".EXE")!=NULL)||(strstr(fname.ff_name,".COM")!=NULL))
            findvirus (fname.ff_name);
        y=wherey();
        gotoxy (x,y);
        hav=findnext (&fname);
    }
    p=findfirst ("*.*",&dirment,0x3f);
    if (!p&&dirment.ff_name[0]=='.')  {
        p=findnext (&dirment);
        p=findnext (&dirment);
    }
    while (!p)  {
        if ((dirment.ff_attrib&0x10)==FA_DIREC)  {
            chdir (dirment.ff_name);
            findfile();
            chdir("..");
        }
        p=findnext (&dirment);
    }
}

main (int argc,char *argv[])
{
    char curdrive=getdisk();
    char curpath[256],drive,virdat[16];
    unsigned long n;
    unsigned long dnum;
    int end=0;
    if (argc<2||argv[1][1]!=':')  {
        puts ("Usage:  KILL drive:path [virusdata]");
        return 1;
    }
    if (argc==2) strcpy (virdat,"VIRUS.DAT");
    else strcpy (virdat,argv[2]);
    file=fopen (virdat,"r");
    if (file==NULL) exit(0);
    fseek (file,1,0);
    for (vl=0;vl<ITEM;vl++)  {
        for (dnum=0,n=0;dnum<256;dnum++)  {
            fread (d,1,1,file);
            if (d[0]=='"')  { dat[vl][n]='\0';break;}
            if (d[0]==' ')  continue;
            dat[vl][n]=d[0];
            n++;
        }
        for (dnum=0,n=0;dnum<256;dnum++)  {
            if (fread (d,1,1,file)==NULL)  { string[vl][n]='\0';end=1;break;}
            if (d[0]=='"')  { string[vl][n]='\0';break;}
            if (d[0]<0x20)  continue;
            string[vl][n]=d[0];
            n++;
        }
        strupr (dat[vl]);
        if (end==1) break;
    }
    getcwd (curpath,256);
    drive=toupper(argv[1][0])-'A';
    setdisk (drive);
    chdir ("\\");
    chdir (argv[1]);
    findfile();
    setdisk (curdrive);
    chdir (curpath);
    fclose(file);
    return 0;
}
